home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 1992 August / info-mac-1992.iso / Applications (app) / STvi / stevie 3.10 / main.c < prev    next >
C/C++ Source or Header  |  1991-01-03  |  7KB  |  340 lines

  1. /* $Header: /nw/tony/src/stevie/src/RCS/main.c,v 1.12 89/08/02 19:53:27 tony Exp $
  2.  *
  3.  * The main routine and routines to deal with the input buffer.
  4.  */
  5.  
  6. #include "stevie.h"
  7.  
  8. int Rows;        /* Number of Rows and Columns */
  9. int Columns;        /* in the current window. */
  10.  
  11. char *Realscreen = NULL;    /* What's currently on the screen, a single */
  12.                 /* array of size Rows*Columns. */
  13. char *Nextscreen = NULL;    /* What's to be put on the screen. */
  14.  
  15. char *Filename = NULL;    /* Current file name */
  16.  
  17. LPTR *Filemem;        /* Pointer to the first line of the file */
  18.  
  19. LPTR *Filetop;        /* Line 'above' the start of the file */
  20.  
  21. LPTR *Fileend;        /* Pointer to the end of the file in Filemem. */
  22.             /* (It points to the byte AFTER the last byte.) */
  23.  
  24. LPTR *Topchar;        /* Pointer to the byte in Filemem which is */
  25.             /* in the upper left corner of the screen. */
  26.  
  27. LPTR *Botchar;        /* Pointer to the byte in Filemem which is */
  28.             /* just off the bottom of the screen. */
  29.  
  30. LPTR *Curschar;        /* Pointer to byte in Filemem at which the */
  31.             /* cursor is currently placed. */
  32.  
  33. int Cursrow, Curscol;    /* Current position of cursor */
  34.  
  35. int Cursvcol;        /* Current virtual column, the column number of */
  36.             /* the file's actual line, as opposed to the */
  37.             /* column number we're at on the screen.  This */
  38.             /* makes a difference on lines that span more */
  39.             /* than one screen line. */
  40.  
  41. int Curswant = 0;    /* The column we'd like to be at. This is used */
  42.             /* try to stay in the same column through up/down */
  43.             /* cursor motions. */
  44.  
  45. bool_t set_want_col;    /* If set, then update Curswant the next time */
  46.             /* through cursupdate() to the current virtual */
  47.             /* column. */
  48.  
  49. int State = NORMAL;    /* This is the current state of the command */
  50.             /* interpreter. */
  51.  
  52. int Prenum = 0;        /* The (optional) number before a command. */
  53.  
  54. LPTR *Insstart;        /* This is where the latest insert/append */
  55.             /* mode started. */
  56.  
  57. bool_t Changed = 0;    /* Set to 1 if something in the file has been */
  58.             /* changed and not written out. */
  59.  
  60. char Redobuff[1024];    /* Each command should stuff characters into this */
  61.             /* buffer that will re-execute itself. */
  62.  
  63. char Insbuff[1024];    /* Each insertion gets stuffed into this buffer. */
  64.  
  65. int Ninsert = 0;    /* Number of characters in the current insertion. */
  66. char *Insptr = NULL;
  67.  
  68. bool_t    got_int=FALSE;    /* set to TRUE when an interrupt occurs (if possible) */
  69.  
  70. bool_t    interactive = FALSE;    /* set TRUE when main() is ready to roll */
  71.  
  72. char **files;        /* list of input files */
  73. int  numfiles;        /* number of input files */
  74. int  curfile;        /* number of the current file */
  75.  
  76. #ifndef MACINTOSH
  77. static void
  78. usage()
  79. {
  80.     fprintf(stderr, "usage: stevie [file ...]\n");
  81.     fprintf(stderr, "       stevie -t tag\n");
  82.     fprintf(stderr, "       stevie +[num] file\n");
  83.     fprintf(stderr, "       stevie +/pat  file\n");
  84.     exit(1);
  85. }
  86. #endif
  87.  
  88. main(argc,argv)
  89. int    argc;
  90. char    *argv[];
  91. {
  92.     char    *initstr, *getenv();    /* init string from the environment */
  93.     char    *tag = NULL;        /* tag from command line */
  94.     char    *pat = NULL;        /* pattern from command line */
  95.     int    line = -1;        /* line number from command line */
  96.  
  97.     /*
  98.      * Process the command line arguments.
  99.      */
  100.     if (argc > 1) {
  101.         switch (argv[1][0]) {
  102.         
  103. #ifndef MACINTOSH
  104.         case '-':            /* -t tag */
  105.             if (argv[1][1] != 't')
  106.                 usage();
  107.  
  108.             if (argv[2] == NULL)
  109.                 usage();
  110.  
  111.             Filename = NULL;
  112.             tag = argv[2];
  113.             numfiles = 1;
  114.             break;
  115.  
  116.         case '+':            /* +n or +/pat */
  117.             if (argv[1][1] == '/') {
  118.                 if (argv[2] == NULL)
  119.                     usage();
  120.                 Filename = strsave(argv[2]);
  121.                 pat = &(argv[1][1]);
  122.                 numfiles = 1;
  123.  
  124.             } else if (isdigit(argv[1][1]) || argv[1][1] == NUL) {
  125.                 if (argv[2] == NULL)
  126.                     usage();
  127.                 Filename = strsave(argv[2]);
  128.                 numfiles = 1;
  129.  
  130.                 line = (isdigit(argv[1][1])) ?
  131.                     atoi(&(argv[1][1])) : 0;
  132.             } else
  133.                 usage();
  134.  
  135.             break;
  136. #endif
  137.  
  138.         default:            /* must be a file name */
  139.             Filename = strsave(argv[1]);
  140.             files = &(argv[1]);
  141.             numfiles = argc - 1;
  142.             break;
  143.         }
  144.     } else {
  145.         Filename = NULL;
  146.         numfiles = 1;
  147.     }
  148.     curfile = 0;
  149.  
  150.      if (numfiles > 1)
  151.          fprintf(stderr, "%d files to edit\n", numfiles);
  152.  
  153.     windinit();
  154.  
  155.     /*
  156.      * Allocate LPTR structures for all the various position pointers
  157.      */
  158.      if ((Filemem = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
  159.          (Filetop = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
  160.          (Fileend = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
  161.          (Topchar = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
  162.          (Botchar = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
  163.          (Curschar = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
  164.          (Insstart = (LPTR *) malloc(sizeof(LPTR))) == NULL ) {
  165.         fprintf(stderr, "Can't allocate data structures\n");
  166.         windexit(0);
  167.     }
  168.  
  169.     screenalloc();
  170.     filealloc();        /* Initialize Filemem, Filetop, and Fileend */
  171.  
  172.     screenclear();
  173.  
  174.     if ((initstr = getenv("EXINIT")) != NULL) {
  175.         char *lp, buf[128];
  176.  
  177.         if ((lp = getenv("LINES")) != NULL) {
  178.             sprintf(buf, "%s lines=%s", initstr, lp);
  179.             docmdln(buf);
  180.         } else
  181.             docmdln(initstr);
  182.     }
  183.  
  184.     if (Filename != NULL) {
  185.         if (readfile(Filename, Filemem, FALSE))
  186.             filemess("[New File]");
  187.     } else if (tag == NULL)
  188.         msg("Empty Buffer");
  189.  
  190.     setpcmark();
  191.  
  192. #ifndef MACINTOSH
  193.     if (tag) {
  194.         stuffin(":ta ");
  195.         stuffin(tag);
  196.         stuffin("\n");
  197.  
  198.     } else if (pat) {
  199.         stuffin(pat);
  200.         stuffin("\n");
  201.  
  202.     } else if (line >= 0) {
  203.         if (line > 0)
  204.             stuffnum(line);
  205.         stuffin("G");
  206.     }
  207. #endif
  208.  
  209.     interactive = TRUE;
  210.  
  211.     edit();
  212.  
  213.     windexit(0);
  214.  
  215.     return 1;        /* shouldn't be reached */
  216. }
  217.  
  218. #define    RBSIZE    1024
  219. static char getcbuff[RBSIZE];
  220. static char *getcnext = NULL;
  221.  
  222. void
  223. stuffin(s)
  224. char    *s;
  225. {
  226.     if (s == NULL) {        /* clear the stuff buffer */
  227.         getcnext = NULL;
  228.         return;
  229.     }
  230.  
  231.     if (getcnext == NULL) {
  232.         strcpy(getcbuff,s);
  233.         getcnext = getcbuff;
  234.     } else
  235.         strcat(getcbuff,s);
  236. }
  237.  
  238. void
  239. stuffnum(n)
  240. int    n;
  241. {
  242.     char    buf[32];
  243.  
  244.     sprintf(buf, "%d", n);
  245.     stuffin(buf);
  246. }
  247.  
  248. int
  249. vgetc()
  250. {
  251.     register int    c;
  252.  
  253.     /*
  254.      * inchar() may map special keys by using stuffin(). If it does
  255.      * so, it returns -1 so we know to loop here to get a real char.
  256.      */
  257.     do {
  258.         if ( getcnext != NULL ) {
  259.             int nextc = *getcnext++;
  260.             if ( *getcnext == NUL ) {
  261.                 *getcbuff = NUL;
  262.                 getcnext = NULL;
  263.             }
  264.             return(nextc);
  265.         }
  266.         c = inchar();
  267.     } while (c == -1);
  268.  
  269.     return c;
  270. }
  271.  
  272. /*
  273.  * anyinput
  274.  *
  275.  * Return non-zero if input is pending.
  276.  */
  277.  
  278. bool_t
  279. anyinput()
  280. {
  281.     return (getcnext != NULL);
  282. }
  283.  
  284. /*
  285.  * do_mlines() - process mode lines for the current file
  286.  *
  287.  * Returns immediately if the "ml" parameter isn't set.
  288.  */
  289. #define    NMLINES    5    /* no. of lines at start/end to check for modelines */
  290.  
  291. void
  292. do_mlines()
  293. {
  294.     void    chk_mline();
  295.     int    i;
  296.     register LPTR    *p;
  297.  
  298.     if (!P(P_ML))
  299.         return;
  300.  
  301.     p = Filemem;
  302.     for (i=0; i < NMLINES ;i++) {
  303.         chk_mline(p->linep->s);
  304.         if ((p = nextline(p)) == NULL)
  305.             break;
  306.     }
  307.  
  308.     if ((p = prevline(Fileend)) == NULL)
  309.         return;
  310.  
  311.     for (i=0; i < NMLINES ;i++) {
  312.         chk_mline(p->linep->s);
  313.         if ((p = prevline(p)) == NULL)
  314.             break;
  315.     }
  316. }
  317.  
  318. /*
  319.  * chk_mline() - check a single line for a mode string
  320.  */
  321. static void
  322. chk_mline(s)
  323. register char    *s;
  324. {
  325.     register char    *cs;        /* local copy of any modeline found */
  326.     register char    *e;
  327.  
  328.     for (; *s != NUL ;s++) {
  329.         if (strncmp(s, "vi:", 3) == 0 || strncmp(s, "ex:", 3) == 0) {
  330.             cs = strsave(s+3);
  331.             if ((e = strchr(cs, ':')) != NULL) {
  332.                 *e = NUL;
  333.                 stuffin(mkstr(CTRL('o')));
  334.                 docmdln(cs);
  335.             }
  336.             free(cs);
  337.         }
  338.     }
  339. }
  340.